package ws;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import netty.util.StartAndStop;
import org.apache.commons.lang3.RandomUtils;
import test.PerformanceAnalyze;
import ws.client.WebSocketClient;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class OkHttpWsPublic extends StartAndStop {

    static PerformanceAnalyze performanceAnalyze = new PerformanceAnalyze();

    private void performanceAnalyze(JSONObject jsonObject) {
        long creationTime = jsonObject.getLongValue("creationTime");
        if (creationTime != 0) {
            performanceAnalyze.delay(System.currentTimeMillis() - creationTime);
        }
    }

    public void start(String url, int size, boolean enableMerger, String channelPrefix, String env) throws Exception {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);

        List<String> topics = JSON.parseArray("[\"ticker.BTC-29APR22-35000-C\",\"ticker.BTC-25MAR22-16000-P\",\"ticker.BTC-14DEC22-1000-C\",\"ticker.BTC-4MAR22-65000-P\",\"ticker.BTC-4MAR22-34000-P\",\"ticker.BTC-23DEC22-16913-C\",\"ticker.BTC-4MAR22-48000-P\",\"ticker.BTC-4MAR22-34000-C\",\"ticker.BTC-23DEC22-16913-P\",\"ticker.BTC-11MAR22-42000-P\",\"ticker.BTC-24JUN22-40000-P\",\"ticker.BTC-14DEC22-1000-P\",\"ticker.BTC-25MAR22-16000-C\",\"ticker.BTC-23DEC22-70000-C\",\"ticker.BTC-25MAR22-190000-P\",\"ticker.BTC-23DEC22-7-P\",\"ticker.BTC-4MAR22-65000-C\",\"ticker.BTC-23DEC22-7-C\",\"ticker.BTC-11MAR22-40000-C\",\"ticker.BTC-23DEC22-20001-P\",\"ticker.BTC-25MAR22-50000-P\",\"ticker.BTC-25MAR22-95000-P\",\"ticker.BTC-23DEC22-70000-P\",\"ticker.BTC-25MAR22-190000-C\",\"ticker.BTC-25MAR22-130000-C\",\"ticker.BTC-25MAR22-95000-C\",\"ticker.BTC-23DEC22-15-C\",\"ticker.BTC-25MAR22-125000-C\",\"ticker.BTC-23DEC22-20001-C\",\"ticker.BTC-29APR22-50000-C\",\"ticker.BTC-23DEC22-555-P\",\"ticker.BTC-23DEC22-15-P\",\"ticker.BTC-29APR22-35000-P\",\"ticker.BTC-30APR22-188-C\",\"ticker.BTC-29APR22-40000-P\",\"ticker.BTC-23DEC22-8000-C\",\"ticker.BTC-25MAR22-60000-C\",\"ticker.BTC-4MAR22-48000-C\",\"ticker.BTC-30APR22-188-P\",\"ticker.BTC-14DEC22-301-P\",\"ticker.BTC-11MAR22-30000-P\",\"ticker.BTC-25MAR22-125000-P\",\"ticker.BTC-25MAR22-130000-P\",\"ticker.BTC-24JUN22-50000-C\",\"ticker.BTC-24JUN22-25000-C\",\"ticker.BTC-11MAR22-30000-C\",\"ticker.BTC-23DEC22-18030-C\",\"ticker.BTC-25MAR22-35000-C\",\"ticker.BTC-25MAR22-60000-P\",\"ticker.BTC-4MAR22-70000-P\",\"ticker.BTC-25MAR22-35000-P\",\"ticker.BTC-29APR22-40000-C\",\"ticker.BTC-24JUN22-50000-P\",\"ticker.BTC-23DEC22-18030-P\",\"ticker.BTC-14DEC22-301-C\",\"ticker.BTC-23DEC22-18187-C\",\"ticker.BTC-23DEC22-8-P\",\"ticker.BTC-4MAR22-38000-P\",\"ticker.BTC-23DEC22-5565-C\",\"ticker.BTC-24JUN22-35000-P\",\"ticker.BTC-23DEC22-5565-P\",\"ticker.BTC-4MAR22-70000-C\",\"ticker.BTC-23DEC22-54123-C\",\"ticker.BTC-25MAR22-45000-P\",\"ticker.BTC-23DEC22-555-C\",\"ticker.BTC-23DEC22-8-C\",\"ticker.BTC-11MAR22-32000-P\",\"ticker.BTC-4MAR22-38000-C\",\"ticker.BTC-4MAR22-44000-P\",\"ticker.BTC-23DEC22-18187-P\",\"ticker.BTC-23DEC22-14-C\",\"ticker.BTC-29APR22-90000-P\",\"ticker.BTC-24JUN22-35000-C\",\"ticker.BTC-24JUN22-150000-P\",\"ticker.BTC-23DEC22-54123-P\",\"ticker.BTC-25MAR22-45000-C\",\"ticker.BTC-11MAR22-42000-C\",\"ticker.BTC-4MAR22-44000-C\",\"ticker.BTC-23DEC22-14-P\",\"ticker.BTC-24JUN22-25000-P\",\"ticker.BTC-25MAR22-10000-C\",\"ticker.BTC-14DEC22-20000-P\",\"ticker.BTC-14DEC22-302-P\",\"ticker.BTC-24JUN22-150000-C\",\"ticker.BTC-23DEC22-100-P\",\"ticker.BTC-25MAR22-135000-P\",\"ticker.BTC-11MAR22-50000-P\",\"ticker.BTC-25MAR22-85000-C\",\"ticker.BTC-25MAR22-55000-P\",\"ticker.BTC-25MAR22-10000-P\",\"ticker.BTC-29APR22-60000-C\",\"ticker.BTC-24JUN22-30000-C\",\"ticker.BTC-14DEC22-20000-C\",\"ticker.BTC-29APR22-30000-P\",\"ticker.BTC-23DEC22-9-P\",\"ticker.BTC-25MAR22-40000-C\",\"ticker.BTC-14DEC22-302-C\",\"ticker.BTC-23DEC22-12457-C\",\"ticker.BTC-23DEC22-15414-C\",\"ticker.BTC-29APR22-90000-C\",\"ticker.BTC-23DEC22-1-P\",\"ticker.BTC-23DEC22-111-C\",\"ticker.BTC-25MAR22-135000-C\",\"ticker.BTC-25MAR22-70000-C\",\"ticker.BTC-11MAR22-32000-C\",\"ticker.BTC-23DEC22-9-C\",\"ticker.BTC-23DEC22-1-C\",\"ticker.BTC-25MAR22-22000-C\",\"ticker.BTC-23DEC22-15414-P\",\"ticker.BTC-23DEC22-17-C\",\"ticker.BTC-25MAR22-85000-P\",\"ticker.BTC-23DEC22-100-C\",\"ticker.BTC-23DEC22-17-P\",\"ticker.BTC-30APR22-144-C\",\"ticker.BTC-25MAR22-55000-C\",\"ticker.BTC-24JUN22-100000-P\",\"ticker.BTC-24JUN22-100000-C\",\"ticker.BTC-11MAR22-36000-P\",\"ticker.BTC-30APR22-144-P\",\"ticker.BTC-11MAR22-28000-P\",\"ticker.BTC-25MAR22-18000-C\",\"ticker.BTC-25MAR22-115000-C\",\"ticker.BTC-24JUN22-20000-P\",\"ticker.BTC-4MAR22-40000-P\",\"ticker.BTC-25MAR22-30000-P\",\"ticker.BTC-23DEC22-8000-P\",\"ticker.BTC-29APR22-100000-C\",\"ticker.BTC-23DEC22-500-P\",\"ticker.BTC-25MAR22-75000-P\",\"ticker.BTC-23DEC22-90000-P\",\"ticker.BTC-11MAR22-28000-C\",\"ticker.BTC-14DEC22-100-P\",\"ticker.BTC-29APR22-50000-P\",\"ticker.BTC-25MAR22-18000-P\",\"ticker.BTC-23DEC22-2-P\",\"ticker.BTC-11MAR22-60000-C\",\"ticker.BTC-4MAR22-46000-P\",\"ticker.BTC-25MAR22-115000-P\",\"ticker.BTC-4MAR22-40000-C\",\"ticker.BTC-4MAR22-46000-C\",\"ticker.BTC-25MAR22-65000-C\",\"ticker.BTC-29APR22-70000-C\",\"ticker.BTC-29APR22-100000-P\",\"ticker.BTC-23DEC22-90000-C\",\"ticker.BTC-23DEC22-111-P\",\"ticker.BTC-25MAR22-105000-C\",\"ticker.BTC-23DEC22-12457-P\",\"ticker.BTC-25MAR22-50000-C\",\"ticker.BTC-24JUN22-40000-C\",\"ticker.BTC-23DEC22-16-C\",\"ticker.BTC-23DEC22-2-C\",\"ticker.BTC-11MAR22-40000-P\",\"ticker.BTC-25MAR22-65000-P\",\"ticker.BTC-25MAR22-1-P\",\"ticker.BTC-25MAR22-105000-P\",\"ticker.BTC-4MAR22-55000-C\",\"ticker.BTC-25MAR22-40000-P\",\"ticker.BTC-23DEC22-80000-C\",\"ticker.BTC-4MAR22-36000-C\",\"ticker.BTC-29APR22-60000-P\",\"ticker.BTC-11MAR22-50000-C\",\"ticker.BTC-23DEC22-16-P\",\"ticker.BTC-30APR22-166-C\",\"ticker.BTC-30APR22-166-P\",\"ticker.BTC-23DEC22-80000-P\",\"ticker.BTC-25MAR22-75000-C\",\"ticker.BTC-4MAR22-36000-P\",\"ticker.BTC-4MAR22-55000-P\",\"ticker.BTC-15APR22-2-C\",\"ticker.BTC-23DEC22-500-C\",\"ticker.BTC-24JUN22-30000-P\",\"ticker.BTC-15APR22-2-P\",\"ticker.BTC-24JUN22-70000-P\",\"ticker.BTC-25MAR22-80000-P\",\"ticker.BTC-24JUN22-120000-C\",\"ticker.BTC-23DEC22-12150-P\",\"ticker.BTC-11MAR22-55000-C\",\"ticker.BTC-4MAR22-50000-C\",\"ticker.BTC-24JUN22-70000-C\",\"ticker.BTC-11MAR22-38000-C\",\"ticker.BTC-23DEC22-3-P\",\"ticker.BTC-4MAR22-50000-P\",\"ticker.BTC-14DEC22-101-P\",\"ticker.BTC-29APR22-20000-C\",\"ticker.BTC-24JUN22-120000-P\",\"ticker.BTC-23DEC22-40000-P\",\"ticker.BTC-25MAR22-15000-P\",\"ticker.BTC-27FEB22-30101-P\",\"ticker.BTC-23DEC22-9000-C\",\"ticker.BTC-25MAR22-1-C\",\"ticker.BTC-25MAR22-15000-C\",\"ticker.BTC-11MAR22-38000-P\",\"ticker.BTC-23DEC22-15541-P\",\"ticker.BTC-27FEB22-30101-C\",\"ticker.BTC-23DEC22-40000-C\",\"ticker.BTC-25MAR22-100000-P\",\"ticker.BTC-23DEC22-11-C\",\"ticker.BTC-11MAR22-60000-P\",\"ticker.BTC-23DEC22-3-C\",\"ticker.BTC-23DEC22-9000-P\",\"ticker.BTC-23DEC22-19-C\",\"ticker.BTC-24JUN22-250000-P\",\"ticker.BTC-25MAR22-20000-P\",\"ticker.BTC-29APR22-70000-P\",\"ticker.BTC-25MAR22-2-P\",\"ticker.BTC-23DEC22-11-P\",\"ticker.BTC-14DEC22-100-C\",\"ticker.BTC-25MAR22-100000-C\",\"ticker.BTC-30APR22-100-C\",\"ticker.BTC-24JUN22-20000-C\",\"ticker.BTC-11MAR22-55000-P\",\"ticker.BTC-29APR22-80000-C\",\"ticker.BTC-23DEC22-100000-P\",\"ticker.BTC-23DEC22-19-P\",\"ticker.BTC-25MAR22-30000-C\",\"ticker.BTC-23DEC22-100000-C\",\"ticker.BTC-24JUN22-250000-C\",\"ticker.BTC-29APR22-10000-P\",\"ticker.BTC-15APR22-1-C\",\"ticker.BTC-30APR22-100-P\",\"ticker.BTC-15APR22-1-P\",\"ticker.BTC-29APR22-80000-P\",\"ticker.BTC-23DEC22-50000-P\",\"ticker.BTC-11MAR22-45000-P\",\"ticker.BTC-29APR22-55000-C\",\"ticker.BTC-25MAR22-155000-P\",\"ticker.BTC-25MAR22-110000-P\",\"ticker.BTC-11MAR22-36000-C\",\"ticker.BTC-25MAR22-90000-C\",\"ticker.BTC-23DEC22-333-P\",\"ticker.BTC-25MAR22-22000-P\",\"ticker.BTC-23DEC22-4-P\",\"ticker.BTC-25MAR22-110000-C\",\"ticker.BTC-25MAR22-155000-C\",\"ticker.BTC-25MAR22-2-C\",\"ticker.BTC-23DEC21-60000-C\",\"ticker.BTC-23DEC22-222-P\",\"ticker.BTC-25MAR22-20000-C\",\"ticker.BTC-23DEC22-15541-C\",\"ticker.BTC-4MAR22-60000-C\",\"ticker.BTC-23DEC22-4-C\",\"ticker.BTC-24JUN22-60000-P\",\"ticker.BTC-29APR22-20000-P\",\"ticker.BTC-23DEC22-18-C\",\"ticker.BTC-24JUN22-60000-C\",\"ticker.BTC-23DEC21-60000-P\",\"ticker.BTC-25MAR22-145000-P\",\"ticker.BTC-23DEC22-222-C\",\"ticker.BTC-14DEC22-101-C\",\"ticker.BTC-25MAR22-70000-P\",\"ticker.BTC-29APR22-30000-C\",\"ticker.BTC-25MAR22-80000-C\",\"ticker.BTC-30APR22-122-C\",\"ticker.BTC-24JUN22-200000-P\",\"ticker.BTC-23DEC22-18-P\",\"ticker.BTC-23DEC22-696-P\",\"ticker.BTC-24JUN22-200000-C\",\"ticker.BTC-23DEC22-50000-C\",\"ticker.BTC-29APR22-55000-P\",\"ticker.BTC-4MAR22-60000-P\",\"ticker.BTC-11MAR22-45000-C\",\"ticker.BTC-30APR22-122-P\",\"ticker.BTC-25MAR22-145000-C\",\"ticker.BTC-4MAR22-42000-C\",\"ticker.BTC-23DEC22-30000-C\",\"ticker.BTC-11MAR22-34000-P\",\"ticker.BTC-25MAR22-120000-C\",\"ticker.BTC-25MAR22-165000-C\",\"ticker.BTC-25MAR22-220000-C\",\"ticker.BTC-23DEC22-696-C\",\"ticker.BTC-25MAR22-220000-P\",\"ticker.BTC-25MAR22-165000-P\",\"ticker.BTC-24JUN22-15000-P\",\"ticker.BTC-25MAR22-120000-P\",\"ticker.BTC-4MAR22-42000-P\",\"ticker.BTC-23DEC22-14649-C\",\"ticker.BTC-23DEC22-5-P\",\"ticker.BTC-23DEC22-10001-C\",\"ticker.BTC-27FEB22-30001-P\",\"ticker.BTC-29APR22-45000-P\",\"ticker.BTC-23DEC22-14649-P\",\"ticker.BTC-23DEC22-10001-P\",\"ticker.BTC-23DEC22-5-C\",\"ticker.BTC-23DEC22-13-C\",\"ticker.BTC-24JUN22-15000-C\",\"ticker.BTC-27FEB22-30001-C\",\"ticker.BTC-29APR22-45000-C\",\"ticker.BTC-23DEC22-13-P\",\"ticker.BTC-23DEC22-3333-C\",\"ticker.BTC-24JUN22-80000-C\",\"ticker.BTC-24JUN22-300000-P\",\"ticker.BTC-23DEC22-333-C\",\"ticker.BTC-25MAR22-90000-P\",\"ticker.BTC-24JUN22-80000-P\",\"ticker.BTC-23DEC22-30000-P\",\"ticker.BTC-23DEC22-3333-P\",\"ticker.BTC-14DEC22-1001-C\",\"ticker.BTC-24JUN22-300000-C\",\"ticker.BTC-25MAR22-185000-P\",\"ticker.BTC-23DEC22-444-C\",\"ticker.BTC-24JUN22-90000-P\",\"ticker.BTC-25MAR22-210000-P\",\"ticker.BTC-29APR22-10000-C\",\"ticker.BTC-23DEC22-10000-C\",\"ticker.BTC-14DEC22-1001-P\",\"ticker.BTC-23DEC22-6-P\",\"ticker.BTC-23DEC22-20000-P\",\"ticker.BTC-25MAR22-210000-C\",\"ticker.BTC-24JUN22-90000-C\",\"ticker.BTC-25MAR22-185000-C\",\"ticker.BTC-23DEC22-6-C\",\"ticker.BTC-25MAR22-175000-C\",\"ticker.BTC-23DEC22-12-C\",\"ticker.BTC-23DEC22-10000-P\",\"ticker.BTC-25MAR22-200000-P\",\"ticker.BTC-23DEC22-20000-C\",\"ticker.BTC-23DEC22-12150-C\",\"ticker.BTC-23DEC22-12-P\",\"ticker.BTC-11MAR22-34000-C\",\"ticker.BTC-25MAR22-175000-P\",\"ticker.BTC-25MAR22-200000-C\",\"ticker.BTC-23DEC22-444-P\"]", String.class);

        List<WebSocketClient> wsList = new LinkedList<>();

        for (int i = 0; i < size; i++) {
            WebSocketClient webSocketClient = WebSocketClient.create(url, msg -> {
                executor.execute(() -> {
                    performanceAnalyze.meter();

                    JSONObject jsonObject = JSON.parseObject(msg);
                    if ("MergedMessage".equals(jsonObject.getString("type"))) {
                        JSONArray jsonArray = jsonObject.getJSONArray("messageList");
                        for (int j = 0; j < jsonArray.size(); j++) {
                            performanceAnalyze(jsonArray.getJSONObject(j));
                        }
                    } else {
                        performanceAnalyze(jsonObject);
                    }
                });
            });
            wsList.add(webSocketClient);
        }

        for (WebSocketClient webSocket : wsList) {
            if (enableMerger) {
                webSocket.send("{\"op\":\"enableMerge\",\"id\":\"1645272016000\",\"args\":[{\"mergeWindow\":\"600\"}]}");
            }

            // {"op":"subscribe","id":"1645784808000","args":["1"]}
            Map<String, Object> subscribe = new HashMap<>();
            subscribe.put("id", String.valueOf(System.currentTimeMillis()));
            subscribe.put("op", "subscribe");
            List<String> args = new LinkedList<>();
            for (int i = 0; i < 60; i++) {
                args.add(topics.get(RandomUtils.nextInt(0, topics.size()-1)));
            }
            subscribe.put("args", args);
            String command = JSON.toJSONString(subscribe);
            webSocket.send(command);

            System.out.println(command);
        }

        for (WebSocketClient webSocket : wsList) {
            Map<String, Object> ping = new HashMap<>();
            ping.put("id", String.valueOf(System.currentTimeMillis()));
            ping.put("op", "ping");

            executor.scheduleAtFixedRate(() -> webSocket.send(JSON.toJSONString(ping)), 1, 10, TimeUnit.SECONDS);

//            Map<String, Object> unSubAll = new HashMap<>();
//            unSubAll.put("id", String.valueOf(System.currentTimeMillis()));
//            unSubAll.put("op", "unSubAll");
//            executor.scheduleAtFixedRate(() -> webSocket.send(JSON.toJSONString(unSubAll)), 1, 10, TimeUnit.SECONDS);
//            executor.scheduleAtFixedRate(() -> webSocket.send("{\"op\":\"fuzzySub\",\"id\":\"1645272018000\",\"args\":[\"ticker\"]}"), 1, 10, TimeUnit.SECONDS);

        }
    }

}
